<!-- CustomModal.vue -->
<template>
  <view class="modal-wrap" v-if="visible" @touchmove.stop.prevent>
    <!-- 遮罩层 -->
    <view class="modal-mask" @click="onClose"></view>

    <!-- 弹窗内容 -->
    <view class="modal-content" :class="{ 'slide-up': animate }">
      <!-- 头部 -->
      <view v-if="showHeader" class="modal-header">
        <text class="modal-title">{{ title }}</text>
        <text v-if="showClose" class="close-btn" @click="onClose">&times;</text>
      </view>

      <!-- 内容区 -->
      <view class="modal-body">
        <slot>{{ content }}</slot>
      </view>

      <!-- 底部按钮 -->
      <view v-if="showFooter" class="modal-footer">
        <button class="btn-cancel" @click="onCancel">{{ cancelText }}</button>
        <button class="btn-confirm" type="primary" @click="onConfirm">{{ confirmText }}</button>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed } from 'vue'

// 定义 Props 类型
interface Props {
  visible: boolean
  title?: string
  content?: string
  cancelText?: string
  confirmText?: string
  closeOnClickModal?: boolean
  animate?: boolean
  showHeader?: boolean
  showFooter?: boolean
  showClose?: boolean
}

// 默认值
const props = withDefaults(defineProps<Props>(), {
  title: '提示',
  content: '',
  cancelText: '取消',
  confirmText: '确定',
  closeOnClickModal: true,
  animate: true,
  showHeader: true,
  showFooter: true,
  showClose: true,
})

// 定义事件
const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void
  (e: 'confirm'): void
  (e: 'cancel'): void
  (e: 'close'): void
}>()

// 使用 computed 避免直接修改 props
const visible = computed(() => props.visible)

// 关闭弹窗（点击遮罩或关闭按钮）
function onClose() {
  if (props.closeOnClickModal) {
    emit('update:visible', false)
    emit('close')
  }
}

// 取消按钮
function onCancel() {
  emit('cancel')
  emit('update:visible', false)
}

// 确定按钮
function onConfirm() {
  emit('confirm')
  // 不自动关闭，由业务控制是否关闭
  // emit('update:visible', false)
}
</script>

<style scoped>
.modal-wrap {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-content {
  width: 80%;
  max-width: 80%;
  background-color: #fff;
  border-radius: 12rpx;
  overflow: hidden;
  transform: translateY(100%);
  opacity: 0;
  transition: transform 0.3s ease-out, opacity 0.3s ease-out;
}

.slide-up {
  transform: translateY(0);
  opacity: 1;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 20px 10px;
  border-bottom: 1px solid #f0f0f0;
}

.modal-title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.close-btn {
  font-size: 24px;
  color: #999;
  width: 30px;
  height: 30px;
  text-align: center;
}

.modal-body {
  padding: 20px;
  color: #666;
  font-size: 14px;
  min-height: 60px;
  line-height: 1.5;
}

.modal-footer {
  display: flex;
  border-top: 1px solid #f0f0f0;
}

.btn-cancel,
.btn-confirm {
  flex: 1;
  height: 90rpx;
  line-height: 90rpx;
  font-size: 16px;
  border: none;
  background: #fff;
  margin: 20rpx 20rpx 30rpx 20rpx;
}

.btn-confirm {
  background: #007aff;
  color: #fff;
}

.btn-cancel {
  color: #999;
  border-right: 1px solid #f0f0f0;
}
</style>
